import {
  IsString,
  IsOptional,
  IsEnum,
  IsBoolean,
  IsDateString,
  MinLength,
  MaxLength,
  IsArray,
  ValidateNested,
  IsUUID,
  IsEmail,
  IsUrl,
  IsIP
} from 'class-validator'
import { Transform, Type } from 'class-transformer'
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'
import { PaginationDto } from './base.dto'
import { IsUrlWithChinese } from '../validators/custom.validators'

/**
 * 评论状态枚举
 */
export enum CommentStatus {
  PENDING = 'pending',
  APPROVED = 'approved',
  REJECTED = 'rejected',
  SPAM = 'spam'
}

/**
 * 评论类型枚举
 */
export enum CommentType {
  COMMENT = 'comment',
  REPLY = 'reply',
  REVIEW = 'review',
  FEEDBACK = 'feedback'
}

/**
 * 创建评论DTO
 */
export class CreateCommentDto {
  @ApiProperty({ description: '评论内容', example: '这篇文章写得很好，学到了很多！' })
  @IsString({ message: '评论内容必须是字符串' })
  @MinLength(1, { message: '评论内容不能为空' })
  @MaxLength(2000, { message: '评论内容不能超过2000个字符' })
  @Transform(({ value }) => value?.trim())
  content: string

  @ApiProperty({ description: '文章ID', example: 'uuid-123' })
  @IsUUID('4', { message: '文章ID格式不正确' })
  articleId: string

  @ApiPropertyOptional({ description: '父评论ID（回复评论时使用）', example: 'uuid-456' })
  @IsOptional()
  @IsUUID('4', { message: '父评论ID格式不正确' })
  parentId?: string

  @ApiPropertyOptional({ description: '评论者姓名（游客评论时使用）', example: '张三' })
  @IsOptional()
  @IsString({ message: '评论者姓名必须是字符串' })
  @MaxLength(50, { message: '评论者姓名不能超过50个字符' })
  @Transform(({ value }) => value?.trim())
  guestName?: string

  @ApiPropertyOptional({
    description: '评论者邮箱（游客评论时使用）',
    example: 'guest@example.com'
  })
  @IsOptional()
  @IsEmail({}, { message: '评论者邮箱格式不正确' })
  @Transform(({ value }) => value?.toLowerCase().trim())
  guestEmail?: string

  @ApiPropertyOptional({
    description: '评论者网站（游客评论时使用）',
    example: 'https://example.com'
  })
  @IsOptional()
  @IsUrlWithChinese({ message: '评论者网站URL格式不正确' })
  guestWebsite?: string

  @ApiPropertyOptional({ description: '评论类型', enum: CommentType, example: CommentType.COMMENT })
  @IsOptional()
  @IsEnum(CommentType, { message: '评论类型不正确' })
  type?: CommentType = CommentType.COMMENT

  @ApiPropertyOptional({ description: '是否接收回复通知', example: true })
  @IsOptional()
  @IsBoolean({ message: '是否接收回复通知必须是布尔值' })
  @Transform(({ value }) => value === 'true' || value === true)
  notifyOnReply?: boolean = true
}

/**
 * 更新评论DTO
 */
export class UpdateCommentDto {
  @ApiPropertyOptional({ description: '评论内容', example: '这篇文章写得很好，学到了很多！' })
  @IsOptional()
  @IsString({ message: '评论内容必须是字符串' })
  @MinLength(1, { message: '评论内容不能为空' })
  @MaxLength(2000, { message: '评论内容不能超过2000个字符' })
  @Transform(({ value }) => value?.trim())
  content?: string

  @ApiPropertyOptional({
    description: '评论状态',
    enum: CommentStatus,
    example: CommentStatus.APPROVED
  })
  @IsOptional()
  @IsEnum(CommentStatus, { message: '评论状态不正确' })
  status?: CommentStatus

  @ApiPropertyOptional({ description: '评论类型', enum: CommentType, example: CommentType.COMMENT })
  @IsOptional()
  @IsEnum(CommentType, { message: '评论类型不正确' })
  type?: CommentType

  @ApiPropertyOptional({ description: '是否接收回复通知', example: true })
  @IsOptional()
  @IsBoolean({ message: '是否接收回复通知必须是布尔值' })
  @Transform(({ value }) => value === 'true' || value === true)
  notifyOnReply?: boolean

  @ApiPropertyOptional({ description: '管理员备注', example: '内容违规，已拒绝' })
  @IsOptional()
  @IsString({ message: '管理员备注必须是字符串' })
  @MaxLength(500, { message: '管理员备注不能超过500个字符' })
  @Transform(({ value }) => value?.trim())
  adminNote?: string
}

/**
 * 评论查询DTO
 */
export class QueryCommentDto extends PaginationDto {
  @ApiPropertyOptional({ description: '搜索关键词（评论内容、评论者姓名）', example: '很好' })
  @IsOptional()
  @IsString({ message: '搜索关键词必须是字符串' })
  @MaxLength(100, { message: '搜索关键词不能超过100个字符' })
  @Transform(({ value }) => value?.trim())
  search?: string = ''

  @ApiPropertyOptional({ description: '文章ID', example: 'uuid-123' })
  @IsOptional()
  @IsUUID('4', { message: '文章ID格式不正确' })
  articleId?: string

  @ApiPropertyOptional({ description: '评论者ID', example: 'uuid-456' })
  @IsOptional()
  @IsUUID('4', { message: '评论者ID格式不正确' })
  authorId?: string

  @ApiPropertyOptional({ description: '父评论ID', example: 'uuid-789' })
  @IsOptional()
  @IsUUID('4', { message: '父评论ID格式不正确' })
  parentId?: string

  @ApiPropertyOptional({
    description: '评论状态',
    enum: CommentStatus,
    example: CommentStatus.APPROVED
  })
  @IsOptional()
  @IsEnum(CommentStatus, { message: '评论状态不正确' })
  status?: CommentStatus

  @ApiPropertyOptional({ description: '评论类型', enum: CommentType, example: CommentType.COMMENT })
  @IsOptional()
  @IsEnum(CommentType, { message: '评论类型不正确' })
  type?: CommentType

  @ApiPropertyOptional({ description: '是否只返回顶级评论', example: true })
  @IsOptional()
  @IsBoolean({ message: '是否只返回顶级评论必须是布尔值' })
  @Transform(({ value }) => value === 'true' || value === true)
  topLevelOnly?: boolean = false

  @ApiPropertyOptional({ description: '是否包含回复', example: true })
  @IsOptional()
  @IsBoolean({ message: '是否包含回复必须是布尔值' })
  @Transform(({ value }) => value === 'true' || value === true)
  includeReplies?: boolean = false

  @ApiPropertyOptional({ description: '创建开始日期', example: '2024-01-01' })
  @IsOptional()
  @IsDateString({}, { message: '创建开始日期格式不正确' })
  createdFrom?: string

  @ApiPropertyOptional({ description: '创建结束日期', example: '2024-12-31' })
  @IsOptional()
  @IsDateString({}, { message: '创建结束日期格式不正确' })
  createdTo?: string
}

/**
 * 评论响应DTO
 */
export class CommentResponseDto {
  @ApiProperty({ description: '评论ID', example: 'uuid-123' })
  id: string

  @ApiProperty({ description: '评论内容', example: '这篇文章写得很好，学到了很多！' })
  content: string

  @ApiProperty({ description: '评论状态', enum: CommentStatus, example: CommentStatus.APPROVED })
  status: CommentStatus

  @ApiProperty({ description: '评论类型', enum: CommentType, example: CommentType.COMMENT })
  type: CommentType

  @ApiProperty({ description: '文章信息' })
  article: {
    id: string
    title: string
    slug: string
  }

  @ApiPropertyOptional({ description: '评论者信息（注册用户）' })
  author?: {
    id: string
    username: string
    realName?: string
    avatar?: string
  }

  @ApiPropertyOptional({ description: '游客评论者信息' })
  guest?: {
    name: string
    email: string
    website?: string
  }

  @ApiPropertyOptional({ description: '父评论ID', example: 'uuid-456' })
  parentId?: string

  @ApiPropertyOptional({ description: '父评论信息' })
  parent?: {
    id: string
    content: string
    authorName: string
  }

  @ApiPropertyOptional({ description: '回复列表' })
  replies?: CommentResponseDto[]

  @ApiProperty({ description: '回复数量', example: 3 })
  replyCount: number

  @ApiProperty({ description: '点赞数量', example: 10 })
  likeCount: number

  @ApiProperty({ description: '点踩数量', example: 1 })
  dislikeCount: number

  @ApiProperty({ description: '是否接收回复通知', example: true })
  notifyOnReply: boolean

  @ApiProperty({ description: '评论者IP地址', example: '192.168.1.1' })
  ipAddress: string

  @ApiProperty({ description: '用户代理', example: 'Mozilla/5.0...' })
  userAgent: string

  @ApiPropertyOptional({ description: '管理员备注', example: '内容优质，已通过审核' })
  adminNote?: string

  @ApiPropertyOptional({ description: '审核者信息' })
  reviewer?: {
    id: string
    username: string
  }

  @ApiPropertyOptional({ description: '审核时间', example: '2024-01-01T00:00:00.000Z' })
  reviewedAt?: Date

  @ApiProperty({ description: '创建时间', example: '2024-01-01T00:00:00.000Z' })
  createdAt: Date

  @ApiProperty({ description: '更新时间', example: '2024-01-01T00:00:00.000Z' })
  updatedAt: Date
}

/**
 * 评论统计DTO
 */
export class CommentStatsDto {
  @ApiProperty({ description: '总评论数', example: 1000 })
  total: number

  @ApiProperty({ description: '待审核评论数', example: 50 })
  pending: number

  @ApiProperty({ description: '已通过评论数', example: 900 })
  approved: number

  @ApiProperty({ description: '已拒绝评论数', example: 30 })
  rejected: number

  @ApiProperty({ description: '垃圾评论数', example: 20 })
  spam: number

  @ApiProperty({ description: '今日新增评论数', example: 15 })
  todayNew: number

  @ApiProperty({ description: '本月新增评论数', example: 200 })
  monthNew: number

  @ApiProperty({ description: '各状态评论数统计' })
  statusStats: Record<CommentStatus, number>

  @ApiProperty({ description: '各类型评论数统计' })
  typeStats: Record<CommentType, number>

  @ApiProperty({ description: '热门评论（按点赞数）' })
  popularComments: Array<{
    id: string
    content: string
    likeCount: number
    articleTitle: string
  }>

  @ApiProperty({ description: '最新评论' })
  recentComments: Array<{
    id: string
    content: string
    authorName: string
    articleTitle: string
    createdAt: Date
  }>

  @ApiProperty({ description: '活跃评论者' })
  activeCommenters: Array<{
    authorName: string
    commentCount: number
    lastCommentAt: Date
  }>
}

/**
 * 批量操作评论DTO
 */
export class BulkCommentOperationDto {
  @ApiProperty({ description: '评论ID列表', example: ['uuid-1', 'uuid-2'] })
  @IsArray({ message: '评论ID列表必须是数组' })
  @IsUUID('4', { each: true, message: '评论ID格式不正确' })
  commentIds: string[]

  @ApiProperty({ description: '操作类型', enum: ['approve', 'reject', 'spam', 'delete'] })
  @IsEnum(['approve', 'reject', 'spam', 'delete'], { message: '操作类型不正确' })
  operation: 'approve' | 'reject' | 'spam' | 'delete'

  @ApiPropertyOptional({ description: '操作原因', example: '批量审核通过' })
  @IsOptional()
  @IsString({ message: '操作原因必须是字符串' })
  @MaxLength(500, { message: '操作原因不能超过500个字符' })
  reason?: string
}

/**
 * 评论点赞DTO
 */
export class LikeCommentDto {
  @ApiProperty({ description: '点赞类型', enum: ['like', 'dislike'], example: 'like' })
  @IsEnum(['like', 'dislike'], { message: '点赞类型不正确' })
  type: 'like' | 'dislike'
}

/**
 * 评论举报DTO
 */
export class ReportCommentDto {
  @ApiProperty({ description: '举报原因', example: '内容不当' })
  @IsString({ message: '举报原因必须是字符串' })
  @MinLength(1, { message: '举报原因不能为空' })
  @MaxLength(500, { message: '举报原因不能超过500个字符' })
  @Transform(({ value }) => value?.trim())
  reason: string

  @ApiPropertyOptional({
    description: '举报类型',
    enum: ['spam', 'inappropriate', 'harassment', 'other']
  })
  @IsOptional()
  @IsEnum(['spam', 'inappropriate', 'harassment', 'other'], { message: '举报类型不正确' })
  type?: 'spam' | 'inappropriate' | 'harassment' | 'other' = 'other'

  @ApiPropertyOptional({ description: '详细描述', example: '该评论包含不当言论' })
  @IsOptional()
  @IsString({ message: '详细描述必须是字符串' })
  @MaxLength(1000, { message: '详细描述不能超过1000个字符' })
  @Transform(({ value }) => value?.trim())
  description?: string
}

/**
 * 评论审核DTO
 */
export class ReviewCommentDto {
  @ApiProperty({ description: '审核结果', enum: CommentStatus, example: CommentStatus.APPROVED })
  @IsEnum([CommentStatus.APPROVED, CommentStatus.REJECTED, CommentStatus.SPAM], {
    message: '审核结果必须是已通过、已拒绝或垃圾评论'
  })
  status: CommentStatus.APPROVED | CommentStatus.REJECTED | CommentStatus.SPAM

  @ApiPropertyOptional({ description: '审核备注', example: '内容符合规范，审核通过' })
  @IsOptional()
  @IsString({ message: '审核备注必须是字符串' })
  @MaxLength(500, { message: '审核备注不能超过500个字符' })
  @Transform(({ value }) => value?.trim())
  adminNote?: string
}
